#sudo stty -F /dev/ttymxc3 cs8 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts
#ssh humia@volta.sdsu.edu -L 3306:127.0.0.1:3306
import time
import serial
import sys
import Levenshtein
import MySQLdb as mdb
import re
import thread
import subprocess

PORT = '/dev/ttymxc3'
BAUD = 115200

#Initialize Serial
def init_serial():
	try:
		global ser
		ser = serial.Serial(PORT,BAUD,timeout=2)
		ser.close()
		ser = serial.Serial(PORT,BAUD,timeout=2)
	except:
		sys.exit("PORT ERROR %s>>>" % PORT)
	else:
		print "CONNECTED TO %s>>>" % PORT
	return

# Send Sketches via Serial (UART) to arduino
def send_sketch(data):
	try:
		ser.write(chr(data))
		print "wrote %d>>>" % data
	except:
		print "UNABLE TO WRITE>>>"
	return

# Prepare motor answer array for sending
def play_ans(x):
	# Breakup motor answer and send
	for item in x:
		if isinstance(item, list):
			for itm in item:
				if isinstance(itm, list):
					buff_sketch(flag_insert(itm))
				else:
					time.sleep((float)(itm)/1000)
		else:
			time.sleep((float)(item)/1000)
	return

# Insert flags into frames (for serial error checking)
def flag_insert(cmd_list):
	if isinstance(cmd_list[0], list):
		# Insert Start of Seq. Flag
		cmd_list.insert(0,255)
		# Insert End of Seq. Flag
		cmd_list.insert(2,254)
	return cmd_list

# Buffer and Send commands
def buff_sketch(seq):
	send_sketch(seq[0])
	#print seq
	for item in seq[1]:
		send_sketch(item)
	send_sketch(seq[2])
	for item in seq[3]:
		send_sketch(item)
	return

# Return index of predicted answer
def find_ans(res,qst):
	res = res.lower()
	i = 0
	for question in qst:
		if Levenshtein.ratio(res, question.lower()) > 0.68:
			return i
		i += 1
	return -1

# Lookup and replace non-integer array strings
def format_seq(lst,dct):
	i = 0
	for item in lst:
		match = re.search('[0-9]', item)
		if match:
			lst[i]= int(item)
		else:
			lst[i]= dct[item]
		i+=1
	return lst

# Load Data from sql DB
def load_data():
	try:
		#Setup Connections
		con = mdb.connect("127.0.0.1","humia","QsUPznMYNDNQ7KtD","humia");
		cur = con.cursor(mdb.cursors.DictCursor)

		# Load Syllables
		cur.execute("SELECT * FROM humia_syllables")
	    	rows = cur.fetchall()
		syllable,words,t_ans,m_ans,qst = {},{},[],[],[]
	    	for row in rows:
			syllable[row["Name"].encode('UTF8')]=[[int(x) for x in row["Speed"].split(",")],[int(x) for x in row["Position"].split(",")]]
	    	
		# Load Words
		cur.execute("SELECT * FROM humia_words")
	    	rows = cur.fetchall()
		words = {}
	    	for row in rows:
			key = row["Name"].encode('UTF8')
			words[key]=format_seq(row["Sequence"].encode('UTF8').split(","),syllable)

		# Load Answers
	    	cur.execute("SELECT * FROM humia_answers ORDER BY ID")
		rows = cur.fetchall()
		for row in rows:
			t_ans.append(row["Text"].encode('UTF8'))
			if (row["Motor"].encode('UTF8') != ''):
				m_ans.append(format_seq(row["Motor"].encode('UTF8').split(","),words))
		cur.execute("SELECT Text FROM humia_questions")
		rows = cur.fetchall()

		# Load Questions
		for row in rows:
			qst.append(row["Text"])

	except mdb.Error, e:
		print "Error %d: %s" % (e.args[0],e.args[1])
		sys.exit(1)
	else:
		return t_ans,m_ans,qst
		con.close()


if __name__ == '__main__':
	init_serial()
	#send_sketch(253)
	t_ans,m_ans,qst = load_data()
	x = m_ans[2]
	#print #t_ans[4]
	#Start sending to Arduino...
	#
	#subprocess.call('rm out.wav', shell=True)
	#xx = "The prerequisites for senior design are E.E 3 30 lab, E.E 4 10, E.E 4 30, E.E 4 34"
	subprocess.call('flite -o out.wav -voice rms -t "'+str(t_ans[2])+'"', shell=True)
	thread.start_new_thread(play_ans, (x,))
	
	subprocess.call('mplayer -af scaletempo -speed 0.6 out.wav', shell=True)
	#PLAY AUDIO (t_ans..{thats the Text Answer!})
	#thread.exit()
	# Use this stuff to test answers
	############
	x =raw_input("CMD:\n")
	while (x.lower() != 'q'):
		pass
	ser.close()
	thread.exit()
	#print t_ans[find_ans(res,qst)]
	


